import _thread
import asyncio
import time
import urllib
from abc import ABC
from concurrent.futures import ThreadPoolExecutor

import tornado
import pysnooper
import tornado.ioloop
import tornado.web
from tornado import gen, httpclient
from tornado.concurrent import run_on_executor
from util.logger_config import logger
from handler.system_handler import SystemHandler
# from log_config import get_logger
from tornado.options import define, options
import tornado.options

# logger = get_logger()
# from config import configuration
# from config import read_config
# import argparse


# 创建解析步骤
# parser = argparse.ArgumentParser(description='Process some integers.')
# # 添加参数步骤
# parser.add_argument('-a', '--active', type=str, default="prod",
#                     help='environment profiles active')
# # 解析参数步骤
# args = parser.parse_args()
# read_config(args.active)
# items = configuration.items("db-server")
# db_server = dict(items)

define("port", default=8888, help="port to listen on")


class MainHandler(tornado.web.RequestHandler, ABC):

    @tornado.gen.coroutine
    @pysnooper.snoop()  # 这个必须贴近下面方法名
    def get(self):
        """
        返回html文本
        :return:
        """

        try:
            raise RuntimeError("错误响应了吗？")
        except Exception as e:
            logger.exception(e)
        # time.sleep(3)
        self.write("Hello, world")

    @pysnooper.snoop()  # 这个必须贴近下面方法名
    def post(self):
        """
        返回json格式
        :return:
        """
        a = 1
        b = 2
        logger.info("%s消息%s" % (a, b))
        self.finish({"tornado": "Hello, world"})

    @pysnooper.snoop()  # 这个必须贴近下面方法名
    def on_finish(self):
        logger.info("on_finish方法响应了")

    def finish(self, chunk=None):
        logger.info("返回数据%s" % chunk)
        super().finish(chunk)

    @pysnooper.snoop()  # 这个必须贴近下面方法名
    def write_error(self, status_code: int, **kwargs):
        logger.error("write_error错误响应了")
        # 若捕获错误，则发送错误信息给client
        exc_cls, exc_instance, trace = kwargs.get("exc_info")
        if status_code != 200:
            self.set_status(status_code)
            self.write({"msg": str(exc_instance)})


async def get_links_from_url(url):
    logger.info("3")

    await asyncio.sleep(2)
    response = await httpclient.AsyncHTTPClient().fetch(url)
    logger.info("4")

    json_body = response.body.decode(errors="ignore")
    logger.info("简印服务器返回内容" + json_body)
    logger.info("5")
    return json_body


class ClientHandler(tornado.web.RequestHandler, ABC):

    async def get(self):
        start_time = time.time()
        logger.info("1")
        current_url = "http://easyprint.vip:9090/"
        urls = asyncio.create_task(get_links_from_url(current_url))
        urls2 = asyncio.create_task(get_links_from_url(current_url))
        await urls
        await urls2
        logger.info("2")
        logger.info(urls)
        end_time = time.time()
        print("消耗时间" + str(end_time - start_time))
        self.write("成功")


class LogHandler(tornado.web.RequestHandler, ABC):

    def post(self):
        decode = self.request.body.decode()
        unquote = urllib.parse.unquote(decode)
        logger.info(unquote)


def print_time(threadName: str, delay: int):
    time.sleep(delay)
    print("线程名:" + threadName)


class ThreadHandler(tornado.web.RequestHandler, ABC):
    executor = ThreadPoolExecutor(10)

    def get(self):
        id = self.get_argument("id")
        logger.info("id" + id)
        try:
            _thread.start_new_thread(print_time, ("Thread-Name1", 2,))
            thread = _thread.start_new_thread(print_time, ("Thread-2", 4,))
        except Exception as e:
            logger.exception(e)
            print("Error: 无法启动线程")

        self.write("多线程并发访问")

    @run_on_executor
    def post(self):
        time.sleep(6)
        logger.info("多线程响应")
        self.write("run_on_executor 多线程响应")


def make_app():
    """
    新建一个tornado web服务
    :return: tornado web服务
    """
    return tornado.web.Application([
        (r"/", MainHandler),
        (r"/easyprint", ClientHandler),
        (r"/thread", ThreadHandler),
        (r"/api/log", LogHandler),
        (r"/system", SystemHandler),
    ],
        autoreload=True,
        debug=True)


if __name__ == "__main__":
    tornado.options.OptionParser().parse_command_line()
    # tornado.options.OptionParser().parse_config_file("./etc/server.conf")

    app = make_app()
    server = tornado.httpserver.HTTPServer(app)
    server.bind(options.port)
    server.start(1)
    logger.info("tornado程序启动成功")
    # server.start(0)  # forks one process per cpu
    tornado.ioloop.IOLoop.current().start()
